import 'dart:convert';
import 'dart:io';
import 'package:crypto/crypto.dart';

import 'package:flutter/material.dart';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:dio/dio.dart';

// 思路：
// 1.第一次打开APP时执行"版本更新"的网络请求；
// 2.比较服务器的版本号跟当前的版本号，来判断要不要升级APP应用程序；
// 3.弹出“版本更新”对话框；
// 4.点击"Later"把时间戳保存下来，每次打开APP获取当前时间戳；
// 5.如果新旧时间戳的差大于或等于一天，执行网络请求(直到点击"DownLoad"为止)；
// 6.点击"DownLoad"直接到 Google Play 官网去下载APK。

class ApkUtils {
  /// 检查更新信息
  static Future<Map<String, dynamic>?> checkForUpdate(String apiUrl) async {
    try {
      final response = await Dio().get(apiUrl);
      if (response.statusCode == 200) {
        return json.decode(response.data);
      }
    } catch (e) {
      debugPrint("检查更新失败: $e");
    }
    return null;
  }

  /// 下载 APK 文件
  static Future<String?> downloadApk(
      String url, String fileName, Function(double) onProgress) async {
    try {
      // 请求存储权限
      if (await Permission.storage.request().isGranted) {
        final directory = await getExternalStorageDirectory();
        final filePath = "${directory!.path}/$fileName";

        Dio dio = Dio();
        await dio.download(
          url,
          filePath,
          onReceiveProgress: (received, total) {
            if (total != -1) {
              double progress = received / total;
              onProgress(progress); // 更新进度回调
            }
          },
        );
        return filePath;
      } else {
        debugPrint("存储权限未授予");
      }
    } catch (e) {
      debugPrint("下载 APK 失败: $e");
    }
    return null;
  }

  /// 校验文件完整性
  static Future<bool> validateFile(String filePath, String checksum) async {
    try {
      final file = File(filePath);
      final bytes = await file.readAsBytes();
      final digest = md5.convert(bytes);
      return digest.toString() == checksum;
    } catch (e) {
      debugPrint("文件校验失败: $e");
    }
    return false;
  }

  /// 安装 APK
  static Future<void> installApk(String filePath) async {
    try {
      final result = await OpenFile.open(filePath);
      debugPrint("安装结果: ${result.message}");
    } catch (e) {
      debugPrint("安装 APK 失败: $e");
    }
  }
}
